package com.xzq.server;

import com.xzq.message.RpcRequestMessage;
import com.xzq.message.RpcResponseMessage;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.socket.SocketChannel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;


import java.lang.reflect.Method;

/**
 * @Author xzq
 * @Description //TODO
 * @Date 2021/11/22 21:21
 * @Version 1.0.0
 **/
@ChannelHandler.Sharable
public class ServerMessageHandler extends SimpleChannelInboundHandler<RpcRequestMessage>   {

    private Logger logger = LoggerFactory.getLogger(ServerMessageHandler.class);

    private BeanFactory beanFactory;

    public ServerMessageHandler(BeanFactory beanFactory) {
        this.beanFactory = beanFactory;
    }

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, RpcRequestMessage rpcRequestMessage) throws Exception {
        RpcResponseMessage response = new RpcResponseMessage();
        logger.info("请收到rpc请求: {}", rpcRequestMessage);
        try {
            //从IOC容器中寻找
            Object bean = beanFactory.getBean(Class.forName(rpcRequestMessage.getInterfaceName()));
            Method method = bean.getClass().getMethod(rpcRequestMessage.getMethodName(), rpcRequestMessage.getParameterTypes());
            Object result = method.invoke(bean, rpcRequestMessage.getParameterValues());
            response.setReturnValue(result);
        } catch (Exception e) {
            response.setExceptionValue(e);
        }
        logger.info("发送response信息:{}",response);
        ctx.writeAndFlush(response);
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        SocketChannel sc = (SocketChannel) ctx.channel();
        logger.info("连接建立.....");
        logger.info("连接ip: {}  连接端口: {}", sc.localAddress().getHostString(), sc.localAddress().getPort());
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        logger.info("连接断开..... 连接信息:{}", ctx.channel().localAddress().toString());
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        logger.error("连接异常:\r\n");
        cause.printStackTrace();
    }

}
